package com.hnkywl.sts.util;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.converters.collections.CollectionConverter;
import com.thoughtworks.xstream.mapper.Mapper;

import java.math.BigDecimal;
import java.util.*;

/**
 * 生成和解析XML相关
 * Created by Fei on 2015/12/21.
 */
public class XmlUtil {

    /**
     *
     * 将实体转换成xml，去掉空格和回车
     *
     * @param msgCode
     *            消息代码
     * @param sysCode
     *            系统代码
     * @param bean
     *            传输数据的Bean
     * @return XML字符串
     */
    public static String generateXml(String msgCode, String sysCode, Object bean) {
        StringBuffer ret = new StringBuffer("<?xml version=\"1.0\" encoding=\"gb2312\"?>");
        ret.append("<Message MsgID=\"" + msgCode + "\" ResourceID=\"" + sysCode + "\">");

        XStream xstream = new XStream();
        xstream.alias("DataRow", bean.getClass());
        String xml = xstream.toXML(bean);

        xml = xml.replaceAll("\n", "");
        xml = xml.replaceAll("  ", "");

        ret.append(xml);
        ret.append("</Message>");

        return ret.toString();
    }

    /**
     * 将List中的数据转换成xml，去掉空格和回车
     *
     * @param msgCode
     *            消息代码
     * @param sysCode
     *            系统代码
     * @param dataList
     *            数据List
     * @param bean
     *            DaoEPBase
     * @return XML字符串
     */
    public static String generateXml(String msgCode, String sysCode, Collection dataList, Class bean) {
        StringBuffer ret = new StringBuffer("<?xml version=\"1.0\" encoding=\"gb2312\"?>");
        ret.append("<Message MsgID=\"" + msgCode + "\" ResourceID=\"" + sysCode + "\">");

        XStream xstream = new XStream();
        Iterator it = dataList.iterator();

        while (it.hasNext()) {
            Object tmp = it.next();
            xstream.alias("DataRow", tmp.getClass());
            String xml = xstream.toXML(tmp);

            xml = xml.replaceAll("\n", "");
            xml = xml.replaceAll("  ", "");
            ret.append(xml);
        }

        ret.append("</Message>");
        return ret.toString();
    }


    /**
     * 当电文中含有单条记录时，解析XML，返回传输的单条记录
     *
     * @param xml
     *            消息内容
     * @param bean
     *            接收消息的Bean
     * @return
     */
    public static Object parseData(String xml, Class bean) {

        xml = xml.replace("\r", " "); //201108006 ADD
        xml = xml.replace("\n", " ");

        XStream xstream = new XStream();
        xstream.alias("DataRow", bean);

        xml = xml.substring(xml.indexOf("<DataRow"));
        xml = xml.substring(0, xml.indexOf("</Message>"));
        Object obj = xstream.fromXML(xml);

        return obj;
    }


    /**
     * 当包含多条数据记录时，解析数据，返回List数据
     *
     * @param xml
     * @param bean
     * @return
     */
    public static List parseList(String xml, Class bean) {
        XStream xstream = new XStream();

        Mapper mapper = xstream.getMapper();
        xstream.registerLocalConverter(ArrayList.class, "Message",
                new CollectionConverter(mapper));

        xstream.alias("Message", ArrayList.class);
        xstream.alias("DataRow", bean);

        xml = xml.substring(xml.indexOf("<Message"));//去掉XML头
        Object obj = xstream.fromXML(xml);

        return (List) obj;
    }


    /**
     * Map转换为XML
     * @param msgCode
     * @param sysCode
     * @param dataMap
     * @return
     */
    public static String hashmapToXml(String msgCode, String sysCode,Map<Object, Object> dataMap) {
        String strBuilder = "";
        strBuilder += "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
        strBuilder += "<Message MsgID=\"" + msgCode + "\" ResourceID=\"" + sysCode + "\">";
        Set<Object> objSet = dataMap.keySet();
        for (Object key : objSet) {
            if (key == null) {
                continue;
            }
            strBuilder += "<" + key.toString() + ">";
            Object value = dataMap.get(key);
            if (value instanceof String || value instanceof BigDecimal
                    || value instanceof Integer || value instanceof Double) {
                strBuilder += value.toString();
            }
            if (value instanceof HashMap) {
                strBuilder += coverter((Map) value);
            }
            if (value instanceof List) {
                strBuilder += coverter((String) key, (List) value);
            }
            strBuilder += "</" + key.toString() + ">";
        }
        strBuilder += "</Message>";
        return strBuilder;
    }

    public static String coverter(Map dataMap) {
        String strBuilder = "";
        Set<Object> objSet = dataMap.keySet();
        for (Object key : objSet) {
            if (key == null) {
                continue;
            }
            Object value = dataMap.get(key);
            if (value instanceof List) {
                strBuilder += coverter((String) key, (List) value);
            }

            if (value instanceof String || value instanceof BigDecimal
                    || value instanceof Integer || value instanceof Double) {
                strBuilder += "<" + key + ">";
                strBuilder += value.toString();
                strBuilder += "</" + key + ">";
            }
        }
        return strBuilder;
    }

    private static Object coverter(String key, List param) {
        if (param == null || param.isEmpty()) {
            return "";
        } else {
            String strBuilder = "";
            for (int i = 0; i < param.size(); i++) {
                strBuilder += "<" + key + ">";
                Object value = param.get(i);
                if (value instanceof HashMap) {
                    strBuilder += coverter((Map) value);
                }
                if (value instanceof String || value instanceof BigDecimal
                        || value instanceof Integer || value instanceof Double) {
                    strBuilder += value.toString();
                }
                strBuilder += "</" + key + ">";
            }
            return strBuilder;
        }
    }

    /**
     * 获取返回XML字符串
     * @param msgCode
     * @param reCode
     * @param reMsg
     * @return
     */
    public static String getReturnXml(String msgCode, String reCode, String reMsg){
        StringBuilder sb = new StringBuilder();
        sb.append("<?xml version=\"1.0\" encoding=\"gb2312\"?>")
                .append("<Message MsgID=\""+ msgCode +"\" ResourceID=\"DH\">")
                .append("<DataRow>")
                .append("<resultCode>"+ reCode +"</resultCode>")
                .append("<resultMessage>"+ reMsg +"</resultMessage>")
                .append("</DataRow>")
                .append("</Message>");

        return  sb.toString();
    }


/*
    public static void main(String[] args) {
        String xmlStr = "<?xml version=\"1.0\" encoding=\" gb2312\"?>" +
                "<Message  MsgID=\" \"  ResourceID=\" \">" +
                "<DataRow>" +
                "<orderItemNum>订单子项号</orderItemNum>" +
                "<companyName>公司名称</companyName>" +
                "<factoryName>制造基地名称</factoryName>" +
                "<signDate>签订日期</signDate>" +
                "<deliveryDate>交货期</deliveryDate >" +
                "<prodName>大类名称</prodName>" +
                "<goodsName>品名</goodsName>" +
                "<spec>规格</spec>" +
                "<shopSign>牌号</shopSign>" +
                "<sellUserName>卖方用户名称</sellUserName>" +
                "<buyUserName>买方用户名称</buyUserName>" +
                "<orderNum>11</orderNum>" +
                "<orderWt>12.12</orderWt>" +
                "<orderAmt>200.23</orderAmt>" +
                "</DataRow>" +
                "</Message>";
        xmlStr = xmlStr.substring(xmlStr.indexOf("<Message"));
        List<XsOrder> list = parseList(xmlStr, XsOrder.class);
        XsOrder xsOrder = (XsOrder) list.get(0);
        System.out.println(xsOrder.getOrderItemNum());
    }
*/


}
